module data_extract(
           input wire clk,
           input wire rst_n,
           input wire din,

           output reg data_abort,
           output reg [15: 0] data,
           output reg data_valid
       );

localparam idle = 3'b001;
localparam head = 3'b010;
localparam tail = 3'b100;

reg [2: 0] cur_state;
reg [2: 0] next_state;
reg skip_flag;
reg abort_flag;
reg [3: 0] cnt;
reg [7: 0] head_tail_reg;

always@(posedge clk or negedge rst_n)
	begin
		if (!rst_n)
			cur_state <= idle;
		else
			cur_state <= next_state;
	end

always@( * )
	begin
		if (!rst_n)
			next_state <= idle;
		else
			begin
				case (cur_state)
					idle:
						begin
							if (skip_flag)
								next_state <= head;
							else
								next_state <= idle;
						end
					head:
						begin
							if (abort_flag)
								next_state <= idle;
							else if (skip_flag)
								next_state <= tail;
							else
								next_state <= head;
						end
					tail:
						begin
							if (skip_flag)
								next_state <= idle;
							else
								next_state <= tail;
						end
					default:
						next_state <= idle;
				endcase
			end
	end

always@(posedge clk or negedge rst_n)
	begin
		if (!rst_n)
			begin
				data_abort <= 1'b0;
				data <= 16'b0;
				data_valid <= 1'b0;
				skip_flag <= 1'b0;
				abort_flag <= 1'b0;
				cnt <= 16'b0;
				head_tail_reg <= 8'b0;
			end
		else
			begin
				cnt <= cnt + 1'b1;
				data <= {data[14: 0], din};
				head_tail_reg <= {head_tail_reg[6: 0], din};
				data_valid <= 1'b0;
				skip_flag <= 1'b0;
				abort_flag <= 1'b0;
				data_abort <= 1'b0;
				case (next_state)
					idle:
						begin
							if (cnt == 4'd7 && {head_tail_reg[6: 0], din} == 8'hae)
								begin
									skip_flag <= 1'b1;
									cnt <= 4'b0;
								end
							else if (cnt == 4'd7)
								begin
									cnt <= 4'b0;
								end
						end
					head:
						begin
							if (cnt == 4'd7 && {head_tail_reg[6: 0], din} == 8'hff)
								begin
									abort_flag <= 1'b1;
									cnt <= 4'b0;
									data_abort <= 1'b1;
								end
							else if (cnt == 4'd15)
								begin
									cnt <= 4'b0;
									skip_flag <= 1'b1;
									data_valid <= 1'b1;
								end
						end
					tail:
						begin
							if (cnt == 4'd7 && {head_tail_reg[6: 0], din} == 8'hff)
								begin
									cnt <= 4'b0;
									skip_flag <= 1'b1;
								end
							else if (cnt == 4'd15)
								begin
									cnt <= 4'b0;
									data_valid <= 1'b1;
								end
						end
				endcase
			end
	end
endmodule
